package main

import (
	"JudgeSandBox/common"
	"JudgeSandBox/utils"
	"bytes"
	"net"
	"os/exec"
	"syscall"
)

func handle(conn net.Conn) error {
	acceptJudgeRequest := make([]byte, 1024*1024) // 最大 1m 数据
	dataLen, err := conn.Read(acceptJudgeRequest)
	if err != nil {
		utils.PrintToLog("接受评判请求失败:", err)
		return err
	} else {
		utils.PrintToLog("接收的数据：", string(acceptJudgeRequest[:dataLen]))
	}

	//调用exec进程

	outBuf := bytes.NewBuffer(make([]byte, 0))
	cmd := exec.Command("/proc/self/exe", "exec")
	cmd.Stdin = bytes.NewBuffer(acceptJudgeRequest[:dataLen]) //传入数据
	cmd.Stdout = outBuf                                       //接收结果数据
	cmd.SysProcAttr = &syscall.SysProcAttr{
		Cloneflags: syscall.CLONE_NEWUTS | syscall.CLONE_NEWPID | syscall.CLONE_NEWNS |
			syscall.CLONE_NEWNET | syscall.CLONE_NEWIPC,
	}

	if err = cmd.Run(); err != nil {
		utils.PrintToLog(err)
	} else {
		if outBuf.Len() > 0 {
			dataBytes := outBuf.Bytes()
			utils.PrintToLog("server得到结果：", string(dataBytes))
			if _, err := conn.Write(dataBytes); err != nil {
				utils.PrintToLog(err)
			}
		} else {
			utils.PrintToLog(conn.RemoteAddr(), "没有错也没有结果！")
		}
	}
	if err := conn.Close(); err != nil {
		utils.PrintToLog(err)
	}
	return nil
}

func start() error {
	listen, err := net.Listen(common.Network, common.Port)
	if err != nil {
		return err
	} else {
		utils.PrintToLog("judge socket start")
	}
	for {
		conn, err := listen.Accept()
		if err != nil {
			utils.PrintToLog("listen accept error:", err.Error())
		} else {
			utils.PrintToLog("remoteAddr:", conn.RemoteAddr())
			go handle(conn)
		}
	}
}
